/*
 * Copyright (C) 2005 - 2013 MaNGOS <http://www.getmangos.com/>
 *
 * Copyright (C) 2008 - 2013 Trinity <http://www.trinitycore.org/>
 *
 * Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
 *
 * Copyright (C) 2010 - 2013 ProjectSkyfire <http://www.projectskyfire.org/>
 *
 * Copyright (C) 2011 - 2013 ArkCORE <http://www.arkania.net/>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

/* ScriptData
 SDName: Boss_Vaelastrasz
 SD%Complete: 75
 SDComment: Burning Adrenaline not correctly implemented in core
 SDCategory: Blackwing Lair
 EndScriptData */

#include "ScriptPCH.h"

#define SAY_LINE1           -1469026
#define SAY_LINE2           -1469027
#define SAY_LINE3           -1469028
#define SAY_HALFLIFE        -1469029
#define SAY_KILLTARGET      -1469030

#define GOSSIP_ITEM         "Start Event <Needs Gossip Text>"

#define SPELL_ESSENCEOFTHERED       23513
#define SPELL_FLAMEBREATH           23461
#define SPELL_FIRENOVA              23462
#define SPELL_TAILSWIPE             15847
#define SPELL_BURNINGADRENALINE     23620
#define SPELL_CLEAVE                20684                   //Chain cleave is most likely named something different and contains a dummy effect
class boss_vaelastrasz: public CreatureScript {
public:
    boss_vaelastrasz() :
            CreatureScript("boss_vaelastrasz") {
    }

    void SendDefaultMenu(Player* pPlayer, Creature* pCreature,
            uint32 uiAction) {
        if (uiAction == GOSSIP_ACTION_INFO_DEF + 1) //Fight time
                {
            pPlayer->CLOSE_GOSSIP_MENU();
            CAST_AI(boss_vaelastrasz::boss_vaelAI, pCreature->AI())->BeginSpeech(
                    pPlayer);
        }
    }

    bool OnGossipSelect(Player* pPlayer, Creature* pCreature, uint32 uiSender,
            uint32 uiAction) {
        pPlayer->PlayerTalkClass->ClearMenus();
        if (uiSender == GOSSIP_SENDER_MAIN)
            SendDefaultMenu(pPlayer, pCreature, uiAction);

        return true;
    }

    bool OnGossipHello(Player* pPlayer, Creature* pCreature) {
        if (pCreature->isQuestGiver())
            pPlayer->PrepareQuestMenu(pCreature->GetGUID());

        pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
        pPlayer->SEND_GOSSIP_MENU(907, pCreature->GetGUID());

        return true;
    }

    CreatureAI* GetAI(Creature* pCreature) const {
        return new boss_vaelAI(pCreature);
    }

    struct boss_vaelAI: public ScriptedAI {
        boss_vaelAI(Creature *c) :
                ScriptedAI(c) {
            c->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
            c->setFaction(35);
            c->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
        }

        uint64 PlayerGUID;
        uint32 SpeechTimer;
        uint32 SpeechNum;
        uint32 Cleave_Timer;
        uint32 FlameBreath_Timer;
        uint32 FireNova_Timer;
        uint32 BurningAdrenalineCaster_Timer;
        uint32 BurningAdrenalineTank_Timer;
        uint32 TailSwipe_Timer;
        bool HasYelled;
        bool DoingSpeech;

        void Reset() {
            PlayerGUID = 0;
            SpeechTimer = 0;
            SpeechNum = 0;
            Cleave_Timer = 8000; //These times are probably wrong
            FlameBreath_Timer = 11000;
            BurningAdrenalineCaster_Timer = 15000;
            BurningAdrenalineTank_Timer = 45000;
            FireNova_Timer = 5000;
            TailSwipe_Timer = 20000;
            HasYelled = false;
            DoingSpeech = false;
        }

        void BeginSpeech(Unit *pTarget) {
            //Stand up and begin speach
            PlayerGUID = pTarget->GetGUID();

            //10 seconds
            DoScriptText(SAY_LINE1, me);

            SpeechTimer = 10000;
            SpeechNum = 0;
            DoingSpeech = true;

            me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
        }

        void KilledUnit(Unit * victim) {
            if (rand() % 5)
                return;

            DoScriptText(SAY_KILLTARGET, me, victim);
        }

        void EnterCombat(Unit * /*who*/) {
            DoCast(me, SPELL_ESSENCEOFTHERED);
            DoZoneInCombat();
            me->SetHealth(me->CountPctFromMaxHealth(30));
        }

        void UpdateAI(const uint32 diff) {
            //Speech
            if (DoingSpeech) {
                if (SpeechTimer <= diff) {
                    switch (SpeechNum) {
                    case 0:
                        //16 seconds till next line
                        DoScriptText(SAY_LINE2, me);
                        SpeechTimer = 16000;
                        ++SpeechNum;
                        break;
                    case 1:
                        //This one is actually 16 seconds but we only go to 10 seconds because he starts attacking after he says "I must fight this!"
                        DoScriptText(SAY_LINE3, me);
                        SpeechTimer = 10000;
                        ++SpeechNum;
                        break;
                    case 2:
                        me->setFaction(103);
                        if (PlayerGUID && Unit::GetUnit((*me), PlayerGUID)) {
                            AttackStart(Unit::GetUnit((*me), PlayerGUID));
                            DoCast(me, SPELL_ESSENCEOFTHERED);
                        }
                        SpeechTimer = 0;
                        DoingSpeech = false;
                        break;
                    }
                } else
                    SpeechTimer -= diff;
            }

            //Return since we have no target
            if (!UpdateVictim())
                return;

            // Yell if hp lower than 15%
            if (HealthBelowPct(15) && !HasYelled) {
                DoScriptText(SAY_HALFLIFE, me);
                HasYelled = true;
            }

            //Cleave_Timer
            if (Cleave_Timer <= diff) {
                DoCast(me->getVictim(), SPELL_CLEAVE);
                Cleave_Timer = 15000;
            } else
                Cleave_Timer -= diff;

            //FlameBreath_Timer
            if (FlameBreath_Timer <= diff) {
                DoCast(me->getVictim(), SPELL_FLAMEBREATH);
                FlameBreath_Timer = urand(4000, 8000);
            } else
                FlameBreath_Timer -= diff;

            //BurningAdrenalineCaster_Timer
            if (BurningAdrenalineCaster_Timer <= diff) {
                Unit *pTarget = NULL;

                uint8 i = 0;
                while (i < 3) // max 3 tries to get a random target with power_mana
                {
                    ++i;
                    pTarget = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true); //not aggro leader
                    if (pTarget && pTarget->getPowerType() == POWER_MANA)
                        i = 3;
                }
                if (pTarget) // cast on self (see below)
                    pTarget->CastSpell(pTarget, SPELL_BURNINGADRENALINE, 1);

                BurningAdrenalineCaster_Timer = 15000;
            } else
                BurningAdrenalineCaster_Timer -= diff;

            //BurningAdrenalineTank_Timer
            if (BurningAdrenalineTank_Timer <= diff) {
                // have the victim cast the spell on himself otherwise the third effect aura will be applied
                // to Vael instead of the player
                me->getVictim()->CastSpell(me->getVictim(),
                        SPELL_BURNINGADRENALINE, 1);

                BurningAdrenalineTank_Timer = 45000;
            } else
                BurningAdrenalineTank_Timer -= diff;

            //FireNova_Timer
            if (FireNova_Timer <= diff) {
                DoCast(me->getVictim(), SPELL_FIRENOVA);
                FireNova_Timer = 5000;
            } else
                FireNova_Timer -= diff;

            //TailSwipe_Timer
            if (TailSwipe_Timer <= diff) {
                //Only cast if we are behind
                /*if (!me->HasInArc(M_PI, me->getVictim()))
                 {
                 DoCast(me->getVictim(), SPELL_TAILSWIPE);
                 }*/

                TailSwipe_Timer = 20000;
            } else
                TailSwipe_Timer -= diff;

            DoMeleeAttackIfReady();
        }
    };
};

void AddSC_boss_vael() {
    new boss_vaelastrasz();
}
